package com.my.ph.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.my.ph.config.entity.UserJsonConfig;
import com.my.ph.dto.PublishHelperParam;
import com.my.ph.entity.media.MediaInfo;
import com.my.ph.entity.media.TVMovie;
import com.my.ph.entity.media.TVMovieDetail;
import com.my.ph.entity.publish.PublishFileInfo;
import com.my.ph.entity.publish.PublishHelperInfo;
import com.my.ph.enums.MediaTypeEnum;
import com.my.ph.media.inter.TvMovieInter;
import com.my.ph.service.MediaService;
import com.my.ph.service.PublishHelperInfoService;
import com.my.ph.util.*;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@Service
@RequiredArgsConstructor
public class MediaServiceImpl implements MediaService {

    @Resource(name = "tmdb")
    private TvMovieInter tmdbTvMovieInter;
    private final TvMovieUtil tvMovieUtil;
    private final PublishHelperInfoService phiService;

    @Override
    public List<TVMovie> search(String keyword) {
        return tmdbTvMovieInter.search(keyword);
    }

    @Override
    public TVMovieDetail getDetail(long id, MediaTypeEnum mediaType) {
        return tmdbTvMovieInter.getDetail(id, mediaType);
    }

    public Map<String, Object> getAutoFeedMap(PublishHelperInfo info, MediaInfo mediaInfo, TVMovieDetail detail) {
        Map<String, Object> params = new HashMap<>();
        params.put("主标题", info.getMainTitle());
        params.put("副标题", info.getSubTitle());
        params.put("IMDB", detail.getImdbId());
        params.put("豆瓣", "");
        params.put("简介", info.getIntro());
        params.put("MediaInfo", info.getInform());
        params.put("种子名称", info.getFolderName() + ".torrent");
        params.put("类型", MediaTypeEnum.MOVIE.getDesc());
        params.put("地区", detail.getOriginZhCountryName());
        params.put("分辨率", mediaInfo.getVideoFormat());
        params.put("音频编码", mediaInfo.getAudioCodec());
        params.put("视频编码", mediaInfo.getVideoCodec());
        params.put("小组", mediaInfo.getSource());
        params.put("媒介", mediaInfo.getTeam());
        params.put("种子链接", info.getTorrentUrl());
        return params;
    }

    public Map<String, Object> reSetAutoFeedMap(PublishHelperInfo info, Map<String, Object> params) {
        params.put("主标题", info.getMainTitle());
        params.put("副标题", info.getSubTitle());
        params.put("简介", info.getIntro());
        params.put("MediaInfo", info.getInform());
        params.put("种子名称", info.getFolderName() + ".torrent");
        params.put("类型", MediaTypeEnum.MOVIE.getDesc());
        params.put("种子链接", info.getTorrentUrl());
        return params;
    }

    public String getAutoFeedUrl(Map<String, Object> params) {
        String url = TemplateReplaceUtil.templateReplaceAutoFeed(UserJsonConfigUtil.getInstance().getAutoFeedLink(), params).replace("#seperator#", "#separator#");
        List<String> split = StrUtil.split(url, "#separator#");
        return split.get(0) + "#separator#" + Base64.encode(URLUtil.encode(split.get(1)));
    }

    public PublishHelperInfo getPublishMedia(TVMovieDetail movieDetail, PublishHelperParam param, String filePath) {
        if (StrUtil.isBlank(filePath)) throw new RuntimeException("文件路径不能为空");
        PublishHelperInfo info = StrUtil.equals(movieDetail.getMediaType(), MediaTypeEnum.MOVIE.getValue()) ? tvMovieUtil.getPublishMovie(movieDetail, param, new File(filePath)) :
                tvMovieUtil.getPublishTv(movieDetail, param, new File(filePath));
        info.setAutoFeedMapObj(getAutoFeedMap(info, info.getMediaInfoObj(), movieDetail));
        return info;
    }

    @Override
    public R<PublishHelperInfo> getPublishHelperInfo(PublishHelperParam param) {
        TVMovieDetail movieDetail = getDetail(param.getId(), MediaTypeEnum.getByValue(param.getMediaType()));
        PublishHelperInfo info = getPublishMedia(movieDetail, param, param.getFilePath());
        phiService.save(info);
        return R.ok(info);
    }

    @Override
    public R<PublishHelperInfo> confirmPublishInfo(PublishHelperInfo info) {
        UserJsonConfig jsonConfig = UserJsonConfigUtil.getInstance();
        PublishHelperInfo dbPh = phiService.getById(info.getId());
        File file = FileUtil.file(dbPh.getFilePath());
        if (!StrUtil.equals(file.getName(), info.getFolderName())) {
            FileUtil.mkdir(file);
            file = FileUtil.rename(file, info.getFolderName(), false, false);
            info.setFilePath(file.getPath());
        }
        File finalFile = file;
        List<PublishFileInfo> publishFileList = dbPh.getPublishFileListObj();
        if (MediaTypeEnum.MOVIE.is(info.getMediaType())) {
            publishFileList.forEach(item -> FileUtil.move(FileUtil.file(item.getInputFilePath()), FileUtil.file(finalFile.getPath() + File.separator + item.getFileName() + "."
                    + FileUtil.getSuffix(item.getInputFilePath())), true));
        } else {
            List<Integer> seasons = dbPh.getSeasonsObj();
            publishFileList.forEach(item -> FileUtil.move(FileUtil.file(item.getInputFilePath()), FileUtil.file(finalFile.getPath() +
                    (jsonConfig.isAutoCreateSeasonFolder() && seasons.size() > 1 ? File.separator + "Season " + item.getSeason() : "") +
                    File.separator + item.getFileName() + "." +
                    FileUtil.getSuffix(item.getInputFilePath())), true));
        }
        info.setPublishFileListObj(publishFileList);
        info.setTorrentPath(TorrentUtil.createTorrent(info.getFilePath(), info.getFolderName(), info.getSource(), info.getId()));
        info.setTorrentUrl(StrUtil.format(StrUtil.format("{}/api/fileDirectory/getTorrent?torrentPath={}", info.getHost(), URLUtil.encode(info.getTorrentPath()))));
        Map<String, Object> autoFeedMap = reSetAutoFeedMap(info, dbPh.getAutoFeedMapObj());
        info.setAutoFeedMapObj(autoFeedMap);
        info.setAutoFeedUrl(getAutoFeedUrl(autoFeedMap));
        info.setMediaInfo(null);
        phiService.updateById(info);
        return R.ok(phiService.getById(info.getId()));
    }
}
